package cc.rengu.igas.mcps.core.service.trans.cardpay;

import cc.rengu.igas.channel.cups.common.constant.CupsConfigConstant;
import cc.rengu.igas.channel.cups.facade.bean.CupsTermInfo;
import cc.rengu.igas.channel.cups.facade.bean.OrigTxnInfo;
import cc.rengu.igas.channel.cups.facade.request.ConsumeRefundRequest;
import cc.rengu.igas.channel.cups.facade.response.ConsumeRefundResponse;
import cc.rengu.igas.mcps.common.constant.McpsParamConstant;
import cc.rengu.igas.mcps.common.constant.McpsTreeNodeConstant;
import cc.rengu.igas.mcps.common.enums.McpsAcctTypeEnum;
import cc.rengu.igas.mcps.common.enums.RespCodeEnum;
import cc.rengu.igas.mcps.core.model.PosTransInfo;
import cc.rengu.igas.mcps.core.realize.PosParamDealService;
import cc.rengu.igas.mcps.core.realize.impl.PosParamDealServiceImpl;
import cc.rengu.igas.mcps.core.service.base.RefundService;
import cc.rengu.igas.mcps.facade.request.PosCardConsumeRefundRequest;
import cc.rengu.igas.mcps.facade.response.PosCardConsumeRefundResponse;
import cc.rengu.igas.share.common.constant.TransCacheConstant;
import cc.rengu.igas.share.core.model.MchntInfo;
import cc.rengu.igas.share.core.model.MchntTermInfo;
import cc.rengu.igas.share.core.realize.MchntService;
import cc.rengu.igas.share.core.realize.impl.MchntServiceImpl;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.entity.ChannelCallCfg;
import cc.rengu.oltp.service.common.entity.MchntOrderInfo;
import cc.rengu.oltp.service.common.entity.PayOrderInfo;
import cc.rengu.oltp.service.common.entity.UserOrderInfo;
import cc.rengu.oltp.service.common.enums.*;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.realize.DubboService;
import cc.rengu.oltp.service.realize.OrderService;
import cc.rengu.oltp.service.realize.impl.DubboServiceImpl;
import cc.rengu.oltp.service.realize.impl.OrderServiceImpl;
import cc.rengu.oltp.utility.util.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.binary.Base64;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class PosCardConsumeRefundService extends RefundService {

    @Override
    protected Object bizBeforeCust() throws Exception {
        PosCardConsumeRefundRequest posCardComsumeRefundReq = new PosCardConsumeRefundRequest();
        ConvertUtil.convertOutput(posCardComsumeRefundReq);
        return posCardComsumeRefundReq;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {

        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        BizResponse bizResponse = new BizResponse();
        PosCardConsumeRefundResponse posCardComsumeRefundRsp = new PosCardConsumeRefundResponse();
        ConvertUtil.convertOutput(posCardComsumeRefundRsp);
        PosCardConsumeRefundRequest posCardComsumeRefundReq = (PosCardConsumeRefundRequest) request;
        String instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        String sysNo = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        String mchntNo = posCardComsumeRefundReq.getMchntNo();
        PosParamDealService posParamDealService = new PosParamDealServiceImpl();
        String refNo = posParamDealService.getRefNo();
        OrderService orderService = new OrderServiceImpl();
        List<MchntOrderInfo> refundMchntOrderInfoList = new ArrayList<>();
        //获取原商户订单
        MchntOrderInfo origMchntOrderInfo = (MchntOrderInfo) GlobalTransUtil.getCacheValue(TransCacheConstant.ORIG_MCHNT_ORDER_INFO);
        //获取原用户订单
        UserOrderInfo origUserOrderInfo = (UserOrderInfo) GlobalTransUtil.getCacheValue(TransCacheConstant.ORIG_USER_ORDER_INFO);
        //获取原通道支付订单
        PayOrderInfo origPayOrderInfoEsb = (PayOrderInfo) GlobalTransUtil.getCacheValue(TransCacheConstant.ORIG_PAY_ORDER_INFO);
        //初始化用户订单表
        UserOrderInfo refundUserOrderInfo = initOrderInfoUser(posCardComsumeRefundReq, origUserOrderInfo);
        //初始化商户订单表
        MchntOrderInfo refundMchntOrderInfo = initOrderInfoMchnt(posCardComsumeRefundReq, refundUserOrderInfo, origMchntOrderInfo);
        /*登记 用户、商户订单表*/
        refundMchntOrderInfoList.add(refundMchntOrderInfo);


        PayOrderInfo payOrderInfoESB = getOrderInfoConsume(posCardComsumeRefundReq, refundMchntOrderInfo, refundUserOrderInfo, origPayOrderInfoEsb, posParamDealService, refNo);
        if (!orderService.registerOrderInfo(refundUserOrderInfo, refundMchntOrderInfoList, payOrderInfoESB)) {
            rglog.error("订单注册失败!!");
            throw new BizException(RespCodeEnum.REGISTER_ORDER_ERROR.getRespCode(), RespCodeEnum.REGISTER_ORDER_ERROR.getRespDesc());
        }

        //转pin
        String newPin = posCardComsumeRefundReq.getPin();
        // 调用esb通道进行退货处理
        //调用本行核心退货接口
        if (McpsAcctTypeEnum.OWN_DEBIT.getAcctType().equals(origPayOrderInfoEsb.getPayerAcctType())) {
            coreRefund(posCardComsumeRefundReq, origUserOrderInfo, origMchntOrderInfo, origPayOrderInfoEsb, newPin,
                    refundMchntOrderInfo, refundUserOrderInfo, payOrderInfoESB, posParamDealService);
        }
        //调用esb银数退货接口
        if (McpsAcctTypeEnum.OWN_CREDIT.getAcctType().equals(origPayOrderInfoEsb.getPayerAcctType())) {
            updcRefund(posCardComsumeRefundReq, origUserOrderInfo, origMchntOrderInfo, origPayOrderInfoEsb, newPin,
                    refundMchntOrderInfo, refundUserOrderInfo, payOrderInfoESB, posParamDealService);
        }
        //调用银联退货接口
        if (McpsAcctTypeEnum.OTHER_DEBIT.getAcctType().equals(origPayOrderInfoEsb.getPayerAcctType()) || McpsAcctTypeEnum.OTHER_CREDIT.getAcctType().equals(origPayOrderInfoEsb.getPayerAcctType())) {
            refund(posCardComsumeRefundReq, origUserOrderInfo, origMchntOrderInfo, origPayOrderInfoEsb,
                    refundMchntOrderInfo, refundUserOrderInfo, payOrderInfoESB, posParamDealService, posCardComsumeRefundRsp, refNo);
        }
        /*特殊费率商户交易成功后调用微信进行消息推送*/
        if ("0".equals(origMchntOrderInfo.getFeeInputMode()) && TransStatusEnum.TRANS_SUCC.getStatus().equals(payOrderInfoESB.getTransStatus()) && BizStatusEnum.FINISH.getStatus().equals(payOrderInfoESB.getBizStatus())) {
            /*调用消息推送*/
            GlobalTransUtil.setCacheValue(TransCacheConstant.USER_ORDER_INFO, refundUserOrderInfo);
            int iReturnCode = asynnotify.transactionNotice("MchntTransNoticeService", 1, 0, 0);
            if (0 != iReturnCode) {
                rglog.error("提交交易结果异步通知给商户失败!");
            }
        }
        /* 重组响应结果 */
        bizResponse.setRspSysId(AppParamConstant.IGAS);
        bizResponse.setRespCode(posCardComsumeRefundRsp.getRespCode());
        bizResponse.setRespDesc(posCardComsumeRefundRsp.getRespDesc());
        bizResponse.setResult(posCardComsumeRefundRsp);
        return bizResponse;
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        PosCardConsumeRefundResponse posCardComsumeRefundRsp = (PosCardConsumeRefundResponse) bizResponse.getResult();
        posCardComsumeRefundRsp.setRespCode(bizResponse.getRespCode());
        posCardComsumeRefundRsp.setRespDesc(bizResponse.getRespDesc());
        ConvertUtil.convertInput(posCardComsumeRefundRsp);
    }

    /**
     * 登记用户订单表
     *
     * @param posCardComsumeRefundReq 请求信息
     * @throws Exception 异常
     */
    private UserOrderInfo initOrderInfoUser(PosCardConsumeRefundRequest posCardComsumeRefundReq, UserOrderInfo oriUserOrderInfo) throws Exception {

        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        UserOrderInfo userOrderInfo = new UserOrderInfo();

        /*获取机构号*/
        String instId = posCardComsumeRefundReq.getHeader().getInstId();
        /*获取交易码*/
        String txnNum = posCardComsumeRefundReq.getHeader().getTxnNum();
        /*获取业务细分*/
        String bizType = posCardComsumeRefundReq.getHeader().getBizType();
        /*获取源系统标识*/
        String msgSrcId = posCardComsumeRefundReq.getHeader().getSrcSysId();
        userOrderInfo.setInstId(instId);
        userOrderInfo.setTxnDate(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TXN_DATE));
        userOrderInfo.setTxnTime(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TXN_TIME));
        userOrderInfo.setTxnNum(txnNum);
        userOrderInfo.setBizType(bizType);
        userOrderInfo.setMsgSrcId(msgSrcId);
        userOrderInfo.setTransChannelId(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TRANS_CHANNEL_ID));
        userOrderInfo.setMchntOrderId(sysSeqNum);
        userOrderInfo.setSysSeqNum(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM));
        userOrderInfo.setOrderCreateTime(DateUtil.getCurrentDateTime("yyyyMMddHHmmss"));
        userOrderInfo.setOrderExpiryTime(DateUtil.getDateByTimeStamp(System.currentTimeMillis() + 5 * 60 * 1000, "yyyyMMddHHmmss"));
        userOrderInfo.setOrderStatus(OrderStatusEnum.INIT.getStatus());
        userOrderInfo.setTransStatus(TransStatusEnum.TRANS_INIT.getStatus());
        userOrderInfo.setBizStatus(BizStatusEnum.PROCESSING.getStatus());
        userOrderInfo.setCreateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        //TODO 待修改
        userOrderInfo.setOrderAmt(posCardComsumeRefundReq.getTransAmt());
        if (AmountUtil.compare(oriUserOrderInfo.getOrderAmt(), posCardComsumeRefundReq.getTransAmt()) == 0) {
            userOrderInfo.setRealPayAmt(oriUserOrderInfo.getRealPayAmt());
        } else {
            userOrderInfo.setRealPayAmt(userOrderInfo.getOrderAmt());
        }
        userOrderInfo.setFrontSeqNum(posCardComsumeRefundReq.getHeader().getTraceNo());
        userOrderInfo.setUserId(posCardComsumeRefundReq.getPayAcctNo());
        userOrderInfo.setOrigTxnDate(oriUserOrderInfo.getTxnDate());
        userOrderInfo.setOrigSysSeqNum(oriUserOrderInfo.getSysSeqNum());
        return userOrderInfo;
    }

    /**
     * 登记商户订单表
     *
     * @param userOrderInfo           用户订单信息
     * @param posCardComsumeRefundReq 请求信息
     * @throws Exception 异常
     */
    private MchntOrderInfo initOrderInfoMchnt(PosCardConsumeRefundRequest posCardComsumeRefundReq, UserOrderInfo userOrderInfo, MchntOrderInfo oriMchntOrderInfo) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        MchntOrderInfo mchntOrderInfo = new MchntOrderInfo();
        /*获取商户基本信息*/
        MchntService mchntService = new MchntServiceImpl();
        MchntInfo mchntInfo = mchntService.getMchntInfo(posCardComsumeRefundReq.getHeader().getInstId(), posCardComsumeRefundReq.getMchntNo());
        if (null == mchntInfo) {
            rglog.error("查询商户基本信息失败<{}>", posCardComsumeRefundReq.getMchntNo());
            throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
        }
        /*内部树复制会把订单状态保存到商户订单信息表*/
        BeanUtil.beanCopy(userOrderInfo, mchntOrderInfo);
        /*设置操作员id*/
        mchntOrderInfo.setUserId(null);
        /*设置商户订单表中业务产品代码*/
        mchntOrderInfo.setBizProdCode(txnInfo.getSrcTxnAuthCfg().getBizProdCode());
        /*收单机构号   从系统参数表中获取value值 即为收单机构号*/
        mchntOrderInfo.setAcqInstCode(mchntInfo.getSignInstId());
        /*行业类别*/
        mchntOrderInfo.setIndustryType(mchntInfo.getIndustryType());
        /*商户号*/
        mchntOrderInfo.setMchntNo(posCardComsumeRefundReq.getMchntNo());
        /*若存在 设置连锁商户门店*/
        if (null != mchntInfo.getChainMchntNo()) {
            mchntOrderInfo.setChainMchntNo(mchntInfo.getChainMchntNo());
        }
        /*商户名称*/
        mchntOrderInfo.setMchntName(mchntInfo.getMchntName());
        /*交易币种*/
        mchntOrderInfo.setOrderCcy(McpsParamConstant.INNER_DEFAULT_ORDERCCY);
        mchntOrderInfo.setRealSettleAmt(mchntOrderInfo.getOrderAmt());
        /*实时清算标识*/
        mchntOrderInfo.setRealSettleFlag(oriMchntOrderInfo.getRealSettleFlag());
        /*创建时间*/
        mchntOrderInfo.setCreateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        /**/
        mchntOrderInfo.setFeeInputMode(oriMchntOrderInfo.getFeeInputMode());
        /*判断是否存在对客营销*/
        if (null != oriMchntOrderInfo.getCustomerMarketAmt()) {
            mchntOrderInfo.setCustomerMarketAmt(oriMchntOrderInfo.getCustomerMarketAmt());
        }

        //非特殊费率商户
        if (!"0".equals(oriMchntOrderInfo.getFeeInputMode())) {
            /*非特殊费率商户  计算手续费*/
            /*判断部分退款 跟全额退款*/
            String realAmount = "";
            if (AmountUtil.compare(oriMchntOrderInfo.getOrderAmt(), oriMchntOrderInfo.getOrderAmt()) == 0) {
                /*全额退款*/
                mchntOrderInfo.setMchntFee(oriMchntOrderInfo.getMchntFee());
                mchntOrderInfo.setMchntDiscountFee(oriMchntOrderInfo.getMchntDiscountFee());
                mchntOrderInfo.setRealMchntFee(oriMchntOrderInfo.getRealMchntFee());
                mchntOrderInfo.setMchntSettleAmt(oriMchntOrderInfo.getMchntSettleAmt());
            } else {
                /*部分退款*/
                /*调用手续费计算接口*/
                rglog.debug("手续费计算数据 原交易总手续费:<{}>,原交易已退款手续费<{}>,原交易已退款金额:<{}>,手续费费率<{}>,固定金额:<{}>,手续费收取方式:<{}>," +
                                "封顶金额:<{}>,原交易订单金额:<{}>,退款订单金额:<{}>,交易码:<{}>",
                        oriMchntOrderInfo.getMchntFee(), oriMchntOrderInfo.getRefundFee(), oriMchntOrderInfo.getRefundAmt(), oriMchntOrderInfo.getFeeRate(),
                        oriMchntOrderInfo.getFeeFixedAmt(), oriMchntOrderInfo.getFeeInputMode(), oriMchntOrderInfo.getFeeCappingAmt(), oriMchntOrderInfo.getOrderAmt(),
                        oriMchntOrderInfo.getOrderAmt(), posCardComsumeRefundReq.getHeader().getTxnNum());
                boolean calcResult = mchntService.calcMchntRefundFee(mchntOrderInfo, oriMchntOrderInfo);
                if (!calcResult) {
                    rglog.error("计算商户手续费失败");
                    throw new BizException(RespCodeEnum.CALC_MCHNT_FEE_ERROR.getRespCode(), RespCodeEnum.CALC_MCHNT_FEE_ERROR.getRespDesc());
                }
                /*商户实际退款手续费*/
                mchntOrderInfo.setRealMchntFee(mchntOrderInfo.getMchntFee());
                /*商户实际退款金额*/
                mchntOrderInfo.setMchntSettleAmt(AmountUtil.subtraction(posCardComsumeRefundReq.getTransAmt(),
                        mchntOrderInfo.getRealMchntFee()));
                if (null == mchntOrderInfo.getRealMchntFee()) {
                    mchntOrderInfo.setRealMchntFee(mchntOrderInfo.getMchntFee());
                }
                if (null == mchntOrderInfo.getMchntDiscountFee()) {
                    mchntOrderInfo.setRealMchntFee("0.000");
                }
                /*商户净额*/
                mchntOrderInfo.setMchntSettleAmt(AmountUtil.subtraction(mchntOrderInfo.getOrderAmt(), mchntOrderInfo.getRealMchntFee()));
            }
        } else {
            mchntOrderInfo.setMchntSettleAmt(mchntOrderInfo.getOrderAmt());
        }

        return mchntOrderInfo;
    }

    /**
     * 登记支付订单表
     *
     * @param posCardComsumeRefundReq 请求信息
     * @throws Exception 异常
     */
    private PayOrderInfo getOrderInfoConsume(PosCardConsumeRefundRequest posCardComsumeRefundReq,
                                             MchntOrderInfo mchntOrderInfo, UserOrderInfo userOrderInfo, PayOrderInfo origPayOrderInfo,
                                             PosParamDealService posParamDealService, String refNo) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String instId = posCardComsumeRefundReq.getHeader().getInstId();
        String sysNum = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.SYS_SEQ_NUM);
        /* 登记支付订单信息 */
        PayOrderInfo payOrderInfo = new PayOrderInfo();
        /*内部树复制会把订单状态保存到商户订单信息表*/
        BeanUtil.beanCopy(mchntOrderInfo, payOrderInfo);
        /*设置交易码*/
        payOrderInfo.setTxnNum(mchntOrderInfo.getTxnNum());
        /*设置订单金额*/
        payOrderInfo.setOrderAmt(userOrderInfo.getOrderAmt());
        /*创建时间*/
        payOrderInfo.setCreateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        /*调用序号*/
        String strIndex = xmlTreeUtil.getXmlTreeStringValue("currentDstCallIndex");
        Integer acctCallIndex = new Integer((StringUtil.isEmptyOrNull(strIndex)) ? "0" : strIndex);
        String dstAcctCallIndex = Integer.toString(acctCallIndex + 1);
        payOrderInfo.setDstCallIndex(acctCallIndex.toString());
        xmlTreeUtil.setXmlTreeStringValue("currentDstCallIndex", dstAcctCallIndex);
        /*支付方式*/
        payOrderInfo.setPayType(origPayOrderInfo.getPayType());
        /*交易通道标识*/
        payOrderInfo.setMsgDstId(ChannelEnum.CUPS.getChannelType());
        payOrderInfo.setChannelOrderId(sysNum);
        /*判断本他行卡 设置对账唯一key*/
        /*本行 */
        if (McpsAcctTypeEnum.OWN_DEBIT.getAcctType().equals(origPayOrderInfo.getPayerAcctType())) {
            /*判断本他行卡 设置对账唯一key*/
            payOrderInfo.setChannelReconKey(payOrderInfo.getChannelOrderId());
            /*通道交易码*/
            payOrderInfo.setDstTxnNum("00010000544002");
        } else if (McpsAcctTypeEnum.OWN_CREDIT.getAcctType().equals(origPayOrderInfo.getPayerAcctType())) {
            /*判断本他行卡 设置对账唯一key*/
            payOrderInfo.setChannelReconKey(payOrderInfo.getChannelOrderId());
            payOrderInfo.setChannelBizType("0000");
            /*通道交易码*/
            payOrderInfo.setDstTxnNum("002600101725B6");
        } else {
            /*通道类型*/
            payOrderInfo.setDstChannelType(ChannelEnum.CUPS.getChannelType());
            /*他行卡 7域+11域+32域+33域*/
            payOrderInfo.setChannelReconKey(posParamDealService.getCupsReconKey(instId, mchntOrderInfo.getMchntNo()));

            ChannelCallCfg channelCallCfgList = txnInfo.getChannelCallCfgList().stream().filter(item -> ChannelEnum.CUPS.getChannelType().equals(item.getCallChannelId())).collect(Collectors.toList()).get(0);
            /*通道交易码*/
            payOrderInfo.setDstTxnNum(channelCallCfgList.getCallChannelTxn());
        }
        /*付款方支付类型*/
        payOrderInfo.setPayerAcctType(origPayOrderInfo.getPayerAcctType());
        if (null != userOrderInfo.getRealPayAmt()) {
            payOrderInfo.setRealPayAmt(userOrderInfo.getRealPayAmt());
        } else {
            payOrderInfo.setRealPayAmt(userOrderInfo.getOrderAmt());
        }
        PosTransInfo posTransInfo = new PosTransInfo();
        BeanUtil.beanCopy(posCardComsumeRefundReq, posTransInfo);
        posTransInfo.setRefNo(refNo);
        payOrderInfo.setPayerRemark(Base64.encodeBase64String(JSONObject.toJSONString(posTransInfo).getBytes()));

        /*收款方信息*/
        payOrderInfo.setPayeeAcctInfo(origPayOrderInfo.getPayeeAcctInfo());
        /*付款方信息*/
        payOrderInfo.setPayerAcctInfo(posCardComsumeRefundReq.getPayAcctNo());

        return payOrderInfo;
    }

    /*本行借记卡 通道调用
     * posCardConsumeRefundRequest
     * origUserOrderInfo
     * origMchntOrderInfo
     * origPayOrderInfoEsb
     * mchntOrderInfo
     * userOrderInfo
     * payOrderInfoESB
     * */
    private void coreRefund(PosCardConsumeRefundRequest posCardConsumeRefundRequest,
                            UserOrderInfo origUserOrderInfo, MchntOrderInfo origMchntOrderInfo,
                            PayOrderInfo origPayOrderInfoEsb, String newPin, MchntOrderInfo mchntOrderInfo,
                            UserOrderInfo userOrderInfo, PayOrderInfo payOrderInfoESB, PosParamDealService posParamDealService) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        OrderService orderService = new OrderServiceImpl();
        DubboService dubboService = new DubboServiceImpl();
        List<MchntOrderInfo> listMchntOrderInfo = new ArrayList<>();
        String instId = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.INST_ID);
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.SYS_SEQ_NUM);
//        /*获取本行内部渠道户*/
//        RoleAcctInfoMapper roleAcctInfoMapper = new RoleAcctInfoMapperImpl();
//        RoleAcctInfoInfo roleAcctInfoInfo = roleAcctInfoMapper.selectRoleAcctInfoByMainKey(instId, "BANK_PAYCHNL_SUBJECT", "866777777");
        /*获取商户基本信息*/
        /*准备请求报文 调起esb接口*/
        //TODO 消费退货  ESB-核心 由项目组进行实现，根据调用结果进行处理
        // （1） 通讯级失败，更新订单数据为失败，非特殊费率商户发起虚拟账户预授权撤销交易 acctDealService.acctAuthCancel，
        // （2） 超时，更新支付订单为超时
        // （3） 交易成功，更新原商户交易订单状态（全额退款或部分退款），更新本次订单为交易成功，
        //         非特殊费率商户发起虚拟账户预授权完成交易acctDealService.acctAuthCompPayment，
        //         调起营销退货comboDealService.comboRefund，
        //         新商户限额、终端限额、交易限额及笔数 mchntService.addTxnLimitStatis


    }

    /*他行借记卡 通道调用
     * posCardConsumeRefundRequest
     * origUserOrderInfo
     * origMchntOrderInfo
     * origPayOrderInfoEsb
     * mchntOrderInfo
     * userOrderInfo
     * payOrderInfoESB
     * */
    private void updcRefund(PosCardConsumeRefundRequest posCardConsumeRefundRequest,
                            UserOrderInfo origUserOrderInfo, MchntOrderInfo origMchntOrderInfo,
                            PayOrderInfo origPayOrderInfoEsb, String newPin, MchntOrderInfo mchntOrderInfo,
                            UserOrderInfo userOrderInfo, PayOrderInfo payOrderInfoESB, PosParamDealService posParamDealService) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        OrderService orderService = new OrderServiceImpl();
        DubboService dubboService = new DubboServiceImpl();
        List<MchntOrderInfo> listMchntOrderInfo = new ArrayList<>();
        /*获取商户基本信息*/
        // TODO 他行卡退款， 由项目组进行实现
        // （1） 通讯级失败，更新订单数据为失败，非特殊费率商户发起虚拟账户预授权撤销交易 acctDealService.acctAuthCancel，
        // （2） 超时，更新支付订单为超时
        // （3） 交易成功，更新原商户交易订单状态（全额退款或部分退款），更新本次订单为交易成功，
        //         非特殊费率商户发起虚拟账户预授权完成交易acctDealService.acctAuthCompPayment，
        //         调起营销退货comboDealService.comboRefund，
        //         新商户限额、终端限额、交易限额及笔数 mchntService.addTxnLimitStatis
    }

    /*他行卡 通道调用
     * posCardConsumeRefundRequest
     * origUserOrderInfo
     * origMchntOrderInfo
     * origPayOrderInfoEsb
     * mchntOrderInfo
     * userOrderInfo
     * payOrderInfoESB
     * */
    private void refund(PosCardConsumeRefundRequest posCardConsumeRefundRequest,
                        UserOrderInfo origUserOrderInfo, MchntOrderInfo origMchntOrderInfo,
                        PayOrderInfo origPayOrderInfoEsb, MchntOrderInfo mchntOrderInfo,
                        UserOrderInfo userOrderInfo, PayOrderInfo payOrderInfoESB, PosParamDealService posParamDealService,
                        PosCardConsumeRefundResponse posCardComsumeRefundRsp, String refNo) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String instId = posCardConsumeRefundRequest.getHeader().getInstId();
        String sysNum = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.SYS_SEQ_NUM);
        DubboService dubboService = new DubboServiceImpl();
        OrderService orderService = new OrderServiceImpl();
        /*获取商户基本信息*/
        MchntService mchntService = new MchntServiceImpl();
        MchntInfo mchntInfo = mchntService.getMchntInfo(instId, posCardConsumeRefundRequest.getMchntNo());
        if (null == mchntInfo) {
            rglog.error("查询商户基本信息失败<{}>", posCardConsumeRefundRequest.getMchntNo());
            throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
        }
        /*初始化请求报文*/
        ConsumeRefundRequest consumeRefundRequest = new ConsumeRefundRequest();
        cc.rengu.igas.channel.cups.facade.base.Header header = new cc.rengu.igas.channel.cups.facade.base.Header();
        BeanUtil.beanCopy(posCardConsumeRefundRequest.getHeader(), header);
        header.setVersion("1.0.0");
        header.setTxnNum(payOrderInfoESB.getDstTxnNum());
        header.setTraceNo(payOrderInfoESB.getChannelOrderId());
        consumeRefundRequest.setHeader(header);
        consumeRefundRequest.setCupsTraceNo(sysNum.substring(sysNum.length() - 6));
        consumeRefundRequest.setTransDateTime(payOrderInfoESB.getTxnDate().substring(4, 8) + payOrderInfoESB.getTxnTime());
        //TODO 待修改
        consumeRefundRequest.setCardSeqNo(posCardConsumeRefundRequest.getCardSeqNo());
        consumeRefundRequest.setMchntNo(posCardConsumeRefundRequest.getMchntNo());
        consumeRefundRequest.setCupsMchntNo(mchntInfo.getCupsMchntNo());
        consumeRefundRequest.setEntryMode(posCardConsumeRefundRequest.getEntryMode());
        consumeRefundRequest.setPayAcctNo(posCardConsumeRefundRequest.getPayAcctNo());
        consumeRefundRequest.setTermNo(posCardConsumeRefundRequest.getTermNo());
        String acqInstCode = posParamDealService.genCupsAcqInstCode(instId, posCardConsumeRefundRequest.getMchntNo());
        String fwdInstCode = XmlConfigUtil.getXmlConfigCacheKeyValue(CupsConfigConstant.CUPS_CONF_NODE, CupsConfigConstant.CUPS_FWD_INS_CODE);
        consumeRefundRequest.setCupsInstCode(acqInstCode);
        consumeRefundRequest.setFwdInstCode(fwdInstCode);
        consumeRefundRequest.setMchntType(mchntOrderInfo.getIndustryType());
        consumeRefundRequest.setIcConCode(posCardConsumeRefundRequest.getIcConCode());
        consumeRefundRequest.setIcData(posCardConsumeRefundRequest.getIcData());
        consumeRefundRequest.setOrderAmt(payOrderInfoESB.getRealPayAmt());
        consumeRefundRequest.setTrack3Data(posCardConsumeRefundRequest.getTrack3Data());
        consumeRefundRequest.setTrack2Data(posCardConsumeRefundRequest.getTrack2Data());
        consumeRefundRequest.setOrderCcy(McpsParamConstant.INNER_DEFAULT_ORDERCCY);
        consumeRefundRequest.setMchntShortName(mchntInfo.getMchntSimpleName());
        consumeRefundRequest.setReferenceNo(refNo);
        if (!StringUtil.isEmptyOrNull(origPayOrderInfoEsb.getTxnAuthCode())) {
            consumeRefundRequest.setAuthCode(origPayOrderInfoEsb.getTxnAuthCode());
        }
        /*原交易信息*/
        OrigTxnInfo origTxnInfo = new OrigTxnInfo();
        origTxnInfo.setOriTxnDate(origPayOrderInfoEsb.getTxnDate());
        origTxnInfo.setOriTraceNo(origPayOrderInfoEsb.getChannelOrderId());
        origTxnInfo.setOriTransDateTime(origPayOrderInfoEsb.getTxnDate().substring(4, 8) + origPayOrderInfoEsb.getTxnTime());
        origTxnInfo.setOriCupsTraceNo(origPayOrderInfoEsb.getSysSeqNum().substring(sysNum.length() - 6, sysNum.length()));

        consumeRefundRequest.setOrigTxnInfo(origTxnInfo);
        consumeRefundRequest.setOrigAmt(origPayOrderInfoEsb.getOrderAmt());
        /*设置终端信息*/
        CupsTermInfo cupsTermInfo = new CupsTermInfo();
        consumeRefundRequest.setTermRead(posCardConsumeRefundRequest.getTermRead());
        BeanUtil.beanCopy(posCardConsumeRefundRequest.getTermInfo(), cupsTermInfo);
        if (StringUtil.isEmptyOrNull(cupsTermInfo.getDeviceType())) {
            MchntTermInfo mchntTermInfo = mchntService.getMchntTermInfo(instId, posCardConsumeRefundRequest.getMchntNo(), posCardConsumeRefundRequest.getTermNo());
            cupsTermInfo.setDeviceType(mchntTermInfo.getTermType());
        }
        consumeRefundRequest.setTermInfo(cupsTermInfo);
        /*打印报文*/
        rglog.info("银联请求报文consumeRefundRequest：<{}>", JSON.toJSONString(consumeRefundRequest));
        cc.rengu.igas.channel.cups.facade.result.Result<ConsumeRefundResponse> result = (cc.rengu.igas.channel.cups.facade.result.Result<ConsumeRefundResponse>) dubboService.callDubboService("cupsPayService", "consumeRefund", consumeRefundRequest);
        /*退货失败处理*/
        if (null == result || null == result.getResult()
                || (!McpsParamConstant.DUBBO_SUCCESS.equals(result.getResult().getRespCode())
                && !McpsParamConstant.DUBBO_OVERTIME.equals(result.getResult().getRespCode())
                && !McpsParamConstant.COMMUNICATION_OVERTIME.equals(result.getResult().getRespCode()))) {
            payOrderInfoESB.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
            payOrderInfoESB.setBizStatus(BizStatusEnum.FAILED.getStatus());
            mchntOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
            mchntOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
            List<MchntOrderInfo> mchntOrderInfoList = new ArrayList<>();
            mchntOrderInfoList.add(mchntOrderInfo);
            userOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
            userOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
            if (!orderService.updateOrderInfo(userOrderInfo, mchntOrderInfoList, payOrderInfoESB)) {
                rglog.error("订单表更新失败");
                throw new BizException(RespCodeEnum.UPDATE_ORDER_ERROR.getRespCode(), RespCodeEnum.UPDATE_ORDER_ERROR.getRespDesc());
            }
        }
        //退货超时处理
        /*判断是否超时*/
        else if (McpsParamConstant.DUBBO_OVERTIME.equals(result.getResult().getRespCode())
                || McpsParamConstant.COMMUNICATION_OVERTIME.equals(result.getResult().getRespCode())) {
            //更新退货订单状态为失败,并更新原交易系统流水号、交易日期
            payOrderInfoESB.setRespCode(result.getResult().getRespCode());
            payOrderInfoESB.setRespDesc(result.getResult().getRespDesc());
            payOrderInfoESB.setTransStatus(TransStatusEnum.TRANS_TIMEOUT.getStatus());
            //更新商户订单状态为失败，并更新原交易系统流水号、交易日期
            mchntOrderInfo.setTransStatus(TransStatusEnum.TRANS_TIMEOUT.getStatus());
            List<MchntOrderInfo> mchntOrderInfoList = new ArrayList<>();
            mchntOrderInfoList.add(mchntOrderInfo);
            //更新用户订单状态为失败，并更新原交易系统流水号、交易日期
            userOrderInfo.setTransStatus(TransStatusEnum.TRANS_TIMEOUT.getStatus());
            if (!orderService.updateOrderInfo(userOrderInfo, mchntOrderInfoList, payOrderInfoESB)) {
                rglog.error("订单表更新失败");
                throw new BizException(RespCodeEnum.UPDATE_ORDER_ERROR.getRespCode(), RespCodeEnum.UPDATE_ORDER_ERROR.getRespDesc());
            }
        }
        //退货成功处理
        else {
            if ((null == origMchntOrderInfo.getRefundAmt() && AmountUtil.compare(posCardConsumeRefundRequest.getTransAmt(), origMchntOrderInfo.getOrderAmt()) == 0) || AmountUtil.compare(AmountUtil.addition(posCardConsumeRefundRequest.getTransAmt(), origMchntOrderInfo.getRefundAmt()), origMchntOrderInfo.getOrderAmt()) == 0) {
                /*更新原三张订单表状态 为 全额退款*/
                origMchntOrderInfo.setBizStatus(BizStatusEnum.REFUND.getStatus());
                origMchntOrderInfo.setRefundAmt(origMchntOrderInfo.getOrderAmt());
                origMchntOrderInfo.setRefundFee(origMchntOrderInfo.getMchntFee());
                origPayOrderInfoEsb.setBizStatus(BizStatusEnum.REFUND.getStatus());
                origUserOrderInfo.setBizStatus(BizStatusEnum.REFUND.getStatus());
                List<MchntOrderInfo> origListMchntOrderInfo = new ArrayList<>();
                origListMchntOrderInfo.add(origMchntOrderInfo);
                if (!orderService.updateOrderInfo(origUserOrderInfo, origListMchntOrderInfo, origPayOrderInfoEsb)) {
                    rglog.error("订单表更新失败");
                    throw new BizException(RespCodeEnum.UPDATE_ORDER_ERROR.getRespCode(), RespCodeEnum.UPDATE_ORDER_ERROR.getRespDesc());
                }
            } else {
                /*更新原三张订单表状态 为 部分退款*/
                origMchntOrderInfo.setBizStatus(BizStatusEnum.PART_REFUND.getStatus());
                origMchntOrderInfo.setRefundAmt(AmountUtil.addition(origMchntOrderInfo.getRefundAmt(), mchntOrderInfo.getOrderAmt()));
                origMchntOrderInfo.setRefundFee(AmountUtil.addition(origMchntOrderInfo.getRefundFee(), mchntOrderInfo.getMchntFee()));
                origPayOrderInfoEsb.setBizStatus(BizStatusEnum.PART_REFUND.getStatus());
                origUserOrderInfo.setBizStatus(BizStatusEnum.PART_REFUND.getStatus());
                List<MchntOrderInfo> origListMchntOrderInfo = new ArrayList<>();
                origListMchntOrderInfo.add(origMchntOrderInfo);
                if (!orderService.updateOrderInfo(origUserOrderInfo, origListMchntOrderInfo, origPayOrderInfoEsb)) {
                    rglog.error("订单表更新失败");
                    throw new BizException(RespCodeEnum.UPDATE_ORDER_ERROR.getRespCode(), RespCodeEnum.UPDATE_ORDER_ERROR.getRespDesc());
                }
            }
            //更新退货交易支付订单交易成功
            payOrderInfoESB.setRespCode(result.getResult().getRespCode());
            payOrderInfoESB.setRespDesc(result.getResult().getRespDesc());
            payOrderInfoESB.setSettleDate(result.getResult().getSettleDate());
            payOrderInfoESB.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
            payOrderInfoESB.setBizStatus(BizStatusEnum.FINISH.getStatus());
            //更新退货交易商户订单交易成功
            mchntOrderInfo.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
            mchntOrderInfo.setBizStatus(BizStatusEnum.FINISH.getStatus());
            List<MchntOrderInfo> mchntOrderInfoList = new ArrayList<>();
            mchntOrderInfoList.add(mchntOrderInfo);
            //更新退货交易用户订单交易成功
            userOrderInfo.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
            userOrderInfo.setBizStatus(BizStatusEnum.FINISH.getStatus());
            userOrderInfo.setOrderStatus(OrderStatusEnum.FINISH.getStatus());
            if (!orderService.updateOrderInfo(userOrderInfo, mchntOrderInfoList, payOrderInfoESB)) {
                rglog.error("订单表更新失败");
                throw new BizException(RespCodeEnum.UPDATE_ORDER_ERROR.getRespCode(), RespCodeEnum.UPDATE_ORDER_ERROR.getRespDesc());
            }
            //更新商户限额、终端限额、交易限额及笔数
            mchntService.updateMchntTransLimit(mchntOrderInfo);
        }

        /*设置返回码 返回信息*/
        if (null == result || !result.isSuccess()) {
            posCardComsumeRefundRsp.setRespCode(OltpRpcdEnum.OLTP_PROCESS_ERROR.getRespCode());
            posCardComsumeRefundRsp.setRespDesc(OltpRpcdEnum.OLTP_PROCESS_ERROR.getRespDesc());
        } else {
            posCardComsumeRefundRsp.setRespCode(result.getResult().getRespCode());
            posCardComsumeRefundRsp.setRespDesc(result.getResult().getRespDesc());
            posCardComsumeRefundRsp.setPayId(sysNum);
            posCardComsumeRefundRsp.setSettleDate(result.getResult().getSettleDate());
            posCardComsumeRefundRsp.setReferenceNo(consumeRefundRequest.getReferenceNo());
            //收单机构
            posCardComsumeRefundRsp.setAcqInstCode(consumeRefundRequest.getCupsInstCode());
            //发卡机构
            posCardComsumeRefundRsp.setPayAcctIssCode(result.getResult().getRcvInstCode());
            posCardComsumeRefundRsp.setTxnDate(consumeRefundRequest.getHeader().getTransDate());
            posCardComsumeRefundRsp.setTxnTime(consumeRefundRequest.getHeader().getTransTime());
        }

    }
}
